package com.zzy.broker.session;

import io.netty.channel.Channel;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 客户端会话信息
 */
public class ClientSession {
    private String clientId;
    private Channel channel;
    private boolean cleanSession;
    private int protocolLevel;
    private String username;
    
    // 订阅的主题列表 (topic -> QoS)
    private final ConcurrentHashMap<String, Integer> subscriptions = new ConcurrentHashMap<>();
    
    // 会话创建时间
    private final long createdTime;
    
    // 最后活跃时间
    private volatile long lastActiveTime;
    
    public ClientSession(String clientId, Channel channel, boolean cleanSession, int protocolLevel, String username) {
        this.clientId = clientId;
        this.channel = channel;
        this.cleanSession = cleanSession;
        this.protocolLevel = protocolLevel;
        this.username = username;
        this.createdTime = System.currentTimeMillis();
        this.lastActiveTime = this.createdTime;
    }
    
    /**
     * 添加订阅
     */
    public void addSubscription(String topic, int qos) {
        subscriptions.put(topic, qos);
        updateLastActiveTime();
    }
    
    /**
     * 移除订阅
     */
    public void removeSubscription(String topic) {
        subscriptions.remove(topic);
        updateLastActiveTime();
    }
    
    /**
     * 获取所有订阅的主题
     */
    public Set<String> getSubscribedTopics() {
        return subscriptions.keySet();
    }
    
    /**
     * 获取指定主题的QoS
     */
    public Integer getSubscriptionQos(String topic) {
        return subscriptions.get(topic);
    }
    
    /**
     * 更新最后活跃时间
     */
    public void updateLastActiveTime() {
        this.lastActiveTime = System.currentTimeMillis();
    }
    
    /**
     * 判断会话是否超时
     */
    public boolean isTimeout(long timeoutMillis) {
        return System.currentTimeMillis() - lastActiveTime > timeoutMillis;
    }
    
    // Getters and Setters
    public String getClientId() {
        return clientId;
    }
    
    public Channel getChannel() {
        return channel;
    }
    
    public void setChannel(Channel channel) {
        this.channel = channel;
    }
    
    public boolean isCleanSession() {
        return cleanSession;
    }
    
    public int getProtocolLevel() {
        return protocolLevel;
    }
    
    public String getUsername() {
        return username;
    }
    
    public long getCreatedTime() {
        return createdTime;
    }
    
    public long getLastActiveTime() {
        return lastActiveTime;
    }
    
    /**
     * 判断Channel是否活跃
     */
    public boolean isActive() {
        return channel != null && channel.isActive();
    }
    
    @Override
    public String toString() {
        return "ClientSession{" +
                "clientId='" + clientId + '\'' +
                ", username='" + username + '\'' +
                ", cleanSession=" + cleanSession +
                ", subscriptions=" + subscriptions.size() +
                ", active=" + isActive() +
                '}';
    }
}
